package com.portal.framework.common;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;

import javax.servlet.ServletOutputStream;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.portal.framework.util.ClassUtil;
import com.portal.framework.util.DateTimeUtil;
import com.portal.framework.util.StringUtils;

/**
 * 
 * @author 卢烁波
 * @date 2007-3-10
 */
public class CommonUtil {
	private static final Log log = LogFactory.getLog(CommonUtil.class);

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public String stringValue(String v, String def) {
		if (v == null)
			return def;
		return v;
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public byte byteValue(String v, byte def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return Byte.parseByte(v);
		} catch (Exception e) {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public char charValue(String v, char def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return (char) Integer.parseInt(v);
		} catch (Exception e) {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public short shortValue(String v, short def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return Short.parseShort(v);
		} catch (Exception e) {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public int intValue(String v, int def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return Integer.parseInt(v);
		} catch (Exception e) {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public long longValue(String v, long def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return Long.parseLong(v);
		} catch (Exception e) {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public boolean booleanValue(String v, boolean def) {
		if (StringUtils.empty(v))
			return def;

		if (v.equalsIgnoreCase("true") || v.equalsIgnoreCase("yes")) {
			return true;
		} else if (v.equalsIgnoreCase("false") || v.equalsIgnoreCase("no")) {
			return false;
		} else {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public float floatValue(String v, float def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return Float.parseFloat(v);
		} catch (Exception e) {
			return def;
		}
	}

	/**
	 * 返回两个字符串中的一个，传入值为空时返回默认的
	 * 
	 * @param v
	 *            传入的
	 * @param def
	 *            默认的
	 * @return
	 */
	static public double doubleValue(String v, double def) {
		if (StringUtils.empty(v))
			return def;
		try {
			return Double.parseDouble(v);
		} catch (Exception e) {
			return def;
		}
	}

	static public double doubleValue(Double v, double def) {
		if (v == null) {
			return 0.0;
		} else {
			return v.doubleValue();
		}
	}

	public static Number decimalValue(String v, Number def) {

		if (v == null || v.length() == 0)
			return def;

		NumberFormat df = DecimalFormat.getInstance();
		try {
			return df.parse(v);
		} catch (Exception e) {
			return def;
		}
	}

	public static boolean isZero(Number num) {
		if (num == null) {
			return true;
		}

		return num.intValue() == 0;
	}

	public static boolean isNotZero(Number num) {
		return !isZero(num);
	}

	/**
	 * 判断一个对象是否为null或默认值
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isNullOrDefaultValue(Object obj) {
		if (obj == null) {
			return true;
		}

		if (obj instanceof String) {
			return StringUtils.empty((String) obj);
		}

		if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return i == null || i == 0;
		}

		if (obj instanceof Byte) {
			Byte i = (Byte) obj;
			return i == null || i == 0;
		}

		if (obj instanceof Short) {
			Short i = (Short) obj;
			return i == null || i == 0;
		}
		if (obj instanceof Long) {
			Long i = (Long) obj;
			return i == null || i == 0;
		}

		// float
		if (obj instanceof Float) {
			Float f = (Float) obj;
			return f == null || f == 0.0;
		}
		if (obj instanceof Double) {
			Double d = (Double) obj;
			return d == null || d == 0.0;
		}

		return false;
	}

	public static boolean isNullOrDefaultValue(Object obj, String defaultValue) {
		if (obj == null) {
			return true;
		}

		if (obj instanceof String && StringUtils.emptyTrimed((String) obj)) {
			return true;
		}

		if (StringUtils.empty(defaultValue)) {
			return isNullOrDefaultValue(obj);
		}

		if (obj instanceof String) {
			String d = (String) obj;
			return d.equals(defaultValue);
		}

		if (obj instanceof Integer) {
			Integer i1 = (Integer) obj;
			Integer i2 = intValue(defaultValue, Integer.MIN_VALUE);
			if (i2 == Integer.MIN_VALUE) {
				return false;
			}
			return i1.equals(i2);
		}

		// byte
		if (obj instanceof Byte) {
			Byte s1 = (Byte) obj;
			Byte s2 = byteValue(defaultValue, Byte.MIN_VALUE);
			if (s2 == Byte.MIN_VALUE) {
				return false;
			}
			return s1.equals(s2);
		}

		// short
		if (obj instanceof Short) {
			Short s1 = (Short) obj;
			Short s2 = shortValue(defaultValue, Short.MIN_VALUE);
			if (s2 == Short.MIN_VALUE) {
				return false;
			}
			return s1.equals(s2);
		}

		// long
		if (obj instanceof Long) {
			Long l1 = (Long) obj;
			Long l2 = longValue(defaultValue, Long.MIN_VALUE);
			if (l2 == Long.MIN_VALUE) {
				return false;
			}
			return l1.equals(l2);
		}

		// float
		if (obj instanceof Float) {
			Float f1 = (Float) obj;
			Float f2 = floatValue(defaultValue, Float.MIN_VALUE);
			if (f2 == Float.MIN_VALUE) {
				return false;
			}
			return f1.equals(f2);
		}

		// double
		if (obj instanceof Double) {
			Double d1 = (Double) obj;
			Double d2 = doubleValue(defaultValue, Double.MIN_VALUE);
			if (d2 == Double.MIN_VALUE) {
				return false;
			}
			return d1.equals(d2);
		}

		return obj == null;
	}

	public static void copyProperties(Object dest, Object src) {
		if (src == null) {
			log.warn(" ### bean copy 源对象为null");
			return;
		}

		try {
			BeanUtils.copyProperties(dest, src);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	

	/**
	 * 将数据生成文件
	 * 
	 * @param sfilename
	 *            文件名带路经
	 * @param data
	 *            需要保存数据
	 * @param s_tab
	 *            分隔号
	 * @throws IOException
	 */
	public static void writeFile(String sfilename, Object[][] data, String s_tab)
			throws IOException {
		String s_path;
		int i, j;
		i = sfilename.lastIndexOf("\\");
		if (i > 0) {
			s_path = sfilename.substring(0, i);
			new File(s_path).mkdirs();
		}
		PrintStream out = new PrintStream(
				new FileOutputStream(sfilename, false), true);

		StringBuffer s_line;
		if (s_tab == null || s_tab.trim().toUpperCase().equals("TAB")) {
			s_tab = "\t";
		}
		int arrayLeng = data.length;
		int dLeng = data[0].length;
		for (i = 0; i < arrayLeng; i++) {
			s_line = new StringBuffer();
			if (data[i][0] != null) {
				for (j = 0; j < dLeng; j++) {
					if (data[i][j] == null) {
						s_line.append("");
					} else {
						if (data[i][j] instanceof java.util.Date) {
							s_line.append(DateTimeUtil.formatDate(
									(java.util.Date) data[i][j],
									DateTimeUtil.DATE_FORMAT));
						} else {
							s_line.append(data[i][j]);
						}
					}
					if (j < dLeng - 1)
						s_line.append(s_tab);
				}
				s_line.append("\r\n");
				out.print(s_line.toString());
			}
		}
		out.close();
	}

	public static void writeFile(ServletOutputStream out, Object[][] data,
			String s_tab) throws IOException {
		int i, j;
		StringBuffer s_line;
		if (s_tab == null || s_tab.trim().toUpperCase().equals("TAB")) {
			s_tab = "\t";
		}
		int arrayLeng = data.length;
		int dLeng = data[0].length;
		BufferedOutputStream out1 = new BufferedOutputStream(out);
		for (i = 0; i < arrayLeng; i++) {
			s_line = new StringBuffer();
			if (data[i][0] != null) {
				for (j = 0; j < dLeng; j++) {
					if (data[i][j] == null) {
						s_line.append("");
					} else {
						if (data[i][j] instanceof java.util.Date) {
							s_line.append(DateTimeUtil.formatDate(
									(java.util.Date) data[i][j],
									DateTimeUtil.DATE_FORMAT));
						} else {
							s_line.append(data[i][j]);
						}
					}
					if (j < dLeng - 1)
						s_line.append(s_tab);
				}
				s_line.append("\r\n");
				out1.write(s_line.toString().getBytes());
			}
		}
		out1.flush();
		out1.close();
	}

	public static double round(double source, int point) {
		return Math.round(source * Math.pow(10, point)) / Math.pow(10, point);
	}

	@SuppressWarnings("unchecked")
	public static <T> Collection<T> extractToCollection(Class<T> cls,
			Collection<?> list, String fieldName) {
		Collection<T> col = new ArrayList<T>();

		for (Object obj : list) {
			T fieldValue = ClassUtil.getFieldValue(obj, fieldName, cls);
			if (fieldValue != null)
				col.add(fieldValue);
		}
		return col;
	}

	/**
	 * 把用户输入的数以小数点为界分割开来，并调用 numFormat() 方法 进行相应的中文金额大写形式的转换
	 * 
	 * @param s
	 *            String
	 * @return 转换好的中文金额大写形式的字符串
	 */
	public static String numberToChina(double d) {
		String s = String.valueOf(d);
		// 如果传入的是空串则继续返回空串
		if ("".equals(s)) {
			return "";
		}
		// 以小数点为界分割这个字符串
		int index = s.indexOf(".");
		// 截取并转换这个数的整数部分
		String intOnly = s.substring(0, index);
		String part1 = numFormat(1, intOnly);
		if(part1.equals("元"))
			part1 = "零"+part1;
		// 截取并转换这个数的小数部分
		String smallOnly = s.substring(index + 1);
		String part2 = numFormat(2, smallOnly);
		// 把转换好了的整数部分和小数部分重新拼凑一个新的字符串
		String newS = "";
		if (!part2.equals(""))
			newS = part1 + part2;
		else
			newS = part1 + "整";
		return newS;
	}

	private static String numFormat(int flag, String s) {
		int sLength = s.length();
		// 货币大写形式
		String bigLetter[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
		// 货币单位
		String unit[] = { "元", "拾", "佰", "仟", "万",
		// 拾万位到仟万位

				"拾", "佰", "仟",
				// 亿位到万亿位
				"亿", "拾", "佰", "仟", "万" };
		String small[] = { "分", "角" };
		// 用来存放转换后的新字符串
		String newS = "";
		// 逐位替换为中文大写形式

		for (int i = 0; i < sLength; i++) {
			if (flag == 1) {
				// 转换整数部分为中文大写形式（带单位）
				if (i == sLength - 1) {// 个位时

					if (s.charAt(i) - 48 != 0)// 个人为0，则不要零字
						newS = newS + bigLetter[s.charAt(i) - 48]
								+ unit[sLength - i - 1];
					else
						newS = newS + unit[sLength - i - 1];
				}
				if (i == sLength - 2 && s.charAt(sLength - 2) - 48 == 0
						&& sLength > 3 && s.charAt(sLength - 1) - 48 != 0)// 百位和个位不为0，十位为0时

				{
					newS = newS + "零";
				}
				if (sLength > 5 && i == sLength - 5
						&& s.charAt(sLength - 5) - 48 == 0) {
					newS = newS + "万";
				} else if (s.charAt(i) - 48 != 0 && i != sLength - 1) {
					newS = newS + bigLetter[s.charAt(i) - 48]
							+ unit[sLength - i - 1];
				}
			} else if (flag == 2) {
				// 转换小数部分（带单位）				
				if(s.charAt(i) - 48!=0){
            		if(sLength==1)
            			newS = newS + bigLetter[s.charAt(i) - 48] + small[1];
            		else
            			newS = newS + bigLetter[s.charAt(i) - 48] + small[sLength - i - 1];
            	}
			}
		}
		return newS;
	}
	
	/**
	 * 增加月数
	 * 
	 * @param source
	 *            日期
	 * @param months
	 *            月数
	 * @return 新日期

	 * 
	 * @author tiack
	 */
	public static Date addMonths(Date source, int months) {
		Date newDate = (Date) source.clone();
		Calendar cal = Calendar.getInstance();
		cal.clear();
		cal.setTime(newDate);
		cal.add(Calendar.MONTH, months);
		return cal.getTime();
	}
	
	/**
	 * 
	 */
	public static String changeCommonFolder(String oldFolder){
//	 String   fs   =   System.getProperties().getProperty( "file.separator");
//	 String commonFolder="";
//	 if(fs.equals("\\"))fs="\\\\";
//		if(oldFolder.indexOf("/")>=0){//window系统目录格式
//			commonFolder=oldFolder.replaceAll("/",fs);
//		}else{//linux unix系统目录格式
//			commonFolder=oldFolder.replaceAll("\\",fs);
//		}
//		return commonFolder;
		return oldFolder;
	}
}
